//microcommand define split
ctx = ctx.platform("onebot")
signature("<text:el>", { strictOptions: true })
action(async ({ session }, els) => {
  const newEls = []
  let textBuffer = []
  let textBufferSize = 0
  function addText(content) {
    while (textBufferSize + content.length >= 4000) {
      let splitPos = 4000
      while (
        content.codePointAt(content.length - (splitPos - 1)) >= 0x10000 ||
        content.substring(splitPos - 1, splitPos + 1).match(/^\s|\s$/)
      )
        splitPos--
      if (splitPos < 0) splitPos = 4000 - textBufferSize
      const left = content.slice(0, splitPos)
      const right = content.slice(splitPos)
      if (typeof textBuffer.at(-1) === "string")
        textBuffer[textBuffer.length - 1] += left
      else textBuffer.push(left)
      newEls.push(h("message", textBuffer))
      textBuffer = []
      textBufferSize = 0
      content = right
    }
    if (typeof textBuffer.at(-1) === "string")
      textBuffer[textBuffer.length - 1] += content
    else textBuffer.push(content)
  }
  function flush() {
    textBuffer.length && newEls.push(h("message", textBuffer))
    textBuffer = []
    textBufferSize = 0
  }
  function walk(els) {
    for (const el of els) {
      if (el.type === "text") {
        addText(el.attrs.content)
      } else if (el.type === "face") {
        textBuffer.push(el)
        textBufferSize += 2
        addText("")
      } else if (el.type === "br") {
        addText("\n")
      } else if (el.type === "p") {
        if (
          textBuffer.length &&
          (typeof textBuffer.at(-1) !== "string" ||
            !textBuffer.at(-1).endsWith("\n"))
        )
          addText("\n")
        walk(el.children)
        addText("\n")
      } else if (el.type === "at") {
        textBuffer.push(el)
        textBufferSize += 32
        addText("")
      } else if (el.type === "a") {
        walk(el.children)
        el.attrs.href && addText(`（${el.attrs.href}）`)
      } else if (
        [
          "img",
          "image",
          "audio",
          "video",
          "file",
          "onebot:music",
          "onebot:json",
          "onebot:xml",
        ].includes(el.type)
      ) {
        flush()
        newEls.push(h("message", el))
      } else if (el.type === "message") {
        flush()
        walk(el.children)
        flush()
      }
    }
  }
  walk(await session.transform(els))
  textBuffer.length && newEls.push(h("message", textBuffer))
  return h("message", { forward: true }, newEls)
})
locale("zh-CN", { description: "用合并转发输出长文本" })